package pers.cz.postgirl.core.enums;


import pers.cz.postgirl.core.store.*;
import pers.cz.postgirl.exception.ErrorCode;
import pers.cz.postgirl.exception.StoreException;

/**
 * @program: postgirl-client
 * @description: 存储策略枚举
 * @author: Cheng Zhi
 * @create: 2023-03-05 13:21
 **/
public enum StoreEnum {
    /**
     * 本地文件存储，一般用于大对象的存储
     */
    LOCAL_FILE("localFile", LocalFileStore.class),

    /**
     * 本地内容存储，一旦重启则全部丢失
     */
    MEMORY("memory", MemoryStore.class),

    /**
     * 数据库存储
     */
    SIMPLE_DB("simpleDb", SimpleDbStore.class),

    /**
     * redis存储
     */
    REDIS("redis", RedisStore.class);

    /**
     * 持久化方案
     */
    String storeName;

    Class<? extends Store> storeClass;

    StoreEnum(String savePlanName, Class<? extends Store> storeClass) {
        this.storeName = savePlanName;
        this.storeClass = storeClass;
    }

    public String getSavePlanName() {
        return storeName;
    }

    public Class<? extends Store> getStoreClass() {
        return storeClass;
    }

    public static Class<? extends Store> getStoreClassByPlanName(String savePlanName) {

        StoreEnum nodeTypeEnum = getEnumBySavePlanName(savePlanName);

        if (nodeTypeEnum == null) {
            throw new StoreException(ErrorCode.SAVE_PLAN_ENUM_IS_NULL_ERROR, savePlanName);
        }
        return nodeTypeEnum.getStoreClass();
    }

    public static StoreEnum getEnumBySavePlanName(String savePlanName) {
        for (StoreEnum anEnum : values()) {
            if (anEnum.getSavePlanName().equalsIgnoreCase(savePlanName)) {
                return anEnum;
            }
        }
        return null;
    }

    /**
     * 反射获取存储对象
     * @param savePlanName
     * @return
     */
    public static Store getStoreInstance(String savePlanName) {

        Class<? extends Store> nodeClassByNodeName = getStoreClassByPlanName(savePlanName);
        Store store = null;
        try {
            store = nodeClassByNodeName.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            throw new StoreException(ErrorCode.SAVE_PLAN_IMPL_IS_NULL_ERROR, savePlanName);
        }

        return store;
    }
}
